package su.msk.jet.team01.chatik.server.commands.authorized;

import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import su.msk.jet.team01.chatik.server.data.Client;
import su.msk.jet.team01.chatik.server.data.ClientManager;
import su.msk.jet.team01.chatik.server.data.DataManager;
import su.msk.jet.team01.chatik.server.db.DatabaseAdapter;
import su.msk.jet.team01.chatik.server.exception.ClientNotFoundException;
import su.msk.jet.team01.chatik.server.exception.InvalidArgumentException;

public class SendPrivateCommand extends AuthorizedCommand {
	private static final String PRIVATE_MESSAGE_PATTERN = "[%s] %s (private) %s: %s";

	private static final String CLIENT_INFO_MSG_TOO_LONG_MESSAGE = "Message is too long. Maximum message length is %d.";

	private static final String CLIENT_INFO_MSG_SEND_PRIVATE_TO_OFFLINE = "Client with name \"%s\" can't be found online, send offline.";

	private static final String CLIENT_INFO_MSG_UNABLE_TO_SAVE_PRIVATE_TO_DB = "Your private message wasn't saved into database";

	private static DatabaseAdapter database = DatabaseAdapter.getInstance();

	private static Logger logger = LoggerFactory
			.getLogger(SendPrivateCommand.class);

	public SendPrivateCommand() {
		super("private", 2);
	}

	@Override
	public void executeAuthorized(final Client client, final String[] args) {
		ClientManager clientManager = DataManager.getClientManager();
		SimpleDateFormat dateTimeFormatter = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
		String date = dateTimeFormatter.format(Calendar.getInstance().getTime());
		String destClientName = args[0];
		String message = args[1];
		Client destClient = null;

		try {
			validateLength(message, MAX_MESSAGE_LENGTH);

			int databaseClientId = clientManager.getClientDatabaseID(client
					.getName());
			int databaseDestId = clientManager
					.getClientDatabaseID(destClientName);

			try {
				logDatabaseMessage(databaseClientId, databaseDestId, message);
			} catch (SQLException ex) {
				logger.error("Can't log private message (from: "
						+ client.getName() + ", to: " + destClientName + ")");
				client.send(CLIENT_INFO_MSG_UNABLE_TO_SAVE_PRIVATE_TO_DB);
			}

			try {
				destClient = clientManager.getClient(destClientName);
				destClient.send(PRIVATE_MESSAGE_PATTERN, date, client.getName(),
						destClientName, message);
			} catch (ClientNotFoundException e) {
				client.send(CLIENT_INFO_MSG_SEND_PRIVATE_TO_OFFLINE,
						destClientName);
			}
			client.send(PRIVATE_MESSAGE_PATTERN, date, client.getName(),
					destClientName, message);
		} catch (InvalidArgumentException e) {
			client.send(CLIENT_INFO_MSG_TOO_LONG_MESSAGE, MAX_MESSAGE_LENGTH);
		}
	}

	private void logDatabaseMessage(final int from, final int to,
			final String message) throws SQLException {
		Calendar c = Calendar.getInstance();
		Date date = c.getTime();

		database.execute(
				"INSERT INTO messages (date, time, from_user_id, to_user_id, message) VALUES (?, ?, ?, ?, ?)",
				new java.sql.Date(date.getTime()),
				new java.sql.Time(date.getTime()), from, to, message);
	}
}